package 
{
	import com.raoway.manager.PopUpManager;
	import com.raoway.manager.StageProxy;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageQuality;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.external.ExternalInterface;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.system.Security;
	import game.manager.GameNameManager;
	import game.manager.LayerManager;
	import game.manager.ResCacheManager;
	import game.manager.StatisticsManager;
	import game.model.config.ConfigManager;
	import game.view.GameView;
	import mx.utils.StringUtil;
	import UIComponent.ResLoading;
	
	/**
	 * ...
	 * @author gcxk721
	 */
	public class GameLoader extends Sprite 
	{
		
		public static var loading:ResLoading;

        private var time:int = 0;
        private var urlLoader:URLLoader;
        private var _mainURL:String;
		
		public function GameLoader():void 
		{
			this.urlLoader = new URLLoader();
            this.urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
            this.urlLoader.addEventListener(Event.COMPLETE, this.completeHandler);
            this.urlLoader.addEventListener(IOErrorEvent.IO_ERROR, this.ioErrorHandler);
            this.urlLoader.addEventListener(ProgressEvent.PROGRESS, this.progressHandler);
            stage.stageFocusRect = false;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            stage.quality = StageQuality.MEDIUM;
            StageProxy.registed(this.stage);
            Security.allowDomain("*");
            Security.allowInsecureDomain("*");
            addChild(GameView.getInstance());
            PopUpManager.layer = LayerManager.topLayer;
            loading = ResLoading.getInstance();
            LayerManager.resLoadingLayer.addChild(loading);
            loading.addEventListener(Event.COMPLETE, this.completeLoadImgHandler);
            loading.setText("正在启动游戏");
            this.loaderInfo.addEventListener(Event.COMPLETE, this.completeInfoHandler);
            new Logger();
		}

		private function completeHandler(evt : Event):void 
		{
			debug("$加载主文件数据成功!");
            var bytes : ByteArray = evt.target.data;
            this.unDecrypt(bytes);
            if (ResCacheManager.getInstance().canCache)
			{
                ResCacheManager.getInstance().setFile(this._mainURL, bytes);
            }
            this.loadMainByte(bytes);
		}
		
		private function ioErrorHandler(e:IOErrorEvent):void 
		{
			this.time++;
            if (this.time >= 3)
			{
                ExternalInterface.call("alert", "启动程序失败，请刷新重试");
            } 
			else 
			{
                this.load();
            }
		}
		
		private function progressHandler(evt : ProgressEvent):void 
		{
			loading.setText("正在启动游戏");
            loading.setProgress(evt.bytesLoaded / evt.bytesTotal * 0.6, 1, evt.bytesLoaded / evt.bytesTotal, 15);
		}
		
		private function completeLoadImgHandler(evt : Event):void 
		{
			this.visible = true;
		}
		
		private function completeInfoHandler(evt : Event):void 
		{
            ConfigManager.parameters = LoaderInfo(evt.target).parameters;
			var param : *;
            for (param in ConfigManager.parameters) 
			{
                ConfigManager.parameters[param] = decodeURI(ConfigManager.parameters[param]);
            }
            var params : Object = ConfigManager.parameters;
            if (ConfigManager.parameters.logo_type != null)
			{
                GameNameManager.getInstance().gameNameType = ConfigManager.parameters.logo_type;
            }
            ConfigManager.setIPConfigData();
            this.loadConfig();
            StatisticsManager.send(7);
            var path : String = StringUtil.substitute("loading.jpg", (int((Math.random() * 3)) + 1));
            loading.loadImg(path + "?v=" + ConfigManager.parameters.r);
            CreateContrller.getInstance().init();
            CreateContrller.getInstance().startSocket();
            if (LanguageManager.isTaiWan())
			{
                TwSubmitController.getInstance().init();
            }
		}
		
		public function load():void
		{
            debug("$加载主文件");
            this.urlLoader.load(new URLRequest(this._mainURL));
        }
		
		private function loadConfig():void
		{
            loading.setText("加载配置文件");
            var urlLoader : URLLoader = new URLLoader();
            urlLoader.addEventListener(Event.COMPLETE, this.completeConfigHandler);
			urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorConfigHandler);
            var url : String = rURL(("assets/config/assetConfig" + GameNameManager.getInstance().gameNameType + ".xml?v=" + String(int(new Date().time / 1000))) + Math.random());
            _local1.load(new URLRequest(url));
            debug("$加载配置");
        }
		
		private function ioErrorConfigHandler(evt : IOErrorEvent):void
		{
            evt.target.removeEventListener(Event.COMPLETE, this.completeConfigHandler);
            evt.target.removeEventListener(IOErrorEvent.IO_ERROR, this.ioErrorConfigHandler);
            this.loadConfig();
        }
		
		private function completeConfigHandler(evt : Event):void
		{
            loading.setProgress(2, 100);
            evt.target.removeEventListener(Event.COMPLETE, this.completeConfigHandler);
            evt.target.removeEventListener(IOErrorEvent.IO_ERROR, this.ioErrorConfigHandler);
            ConfigManager.setConfigData(new XML(_arg1.target.data));
            this.loadResVersion();
        }
		
		private function loadMainByte(bytes : ByteArray):void
		{
            var loader : Loader = new Loader();
            loader.loadBytes(bytes, new LoaderContext(false, ApplicationDomain.currentDomain, null));
            addChildAt(loader, 0);
        }
		
		private function unDecrypt(bytes : ByteArray):ByteArray
		{
            bytes[0] = (bytes[0] ^ 9);
            bytes[1] = (bytes[1] ^ 4);
            bytes[2] = (bytes[2] ^ 8);
            bytes[3] = (bytes[3] ^ 6);
            return bytes;
        }
		
	}
	
}